2018 מבוא למדעי המחשב תרגול 11 תור עץ חיפוש בינארי
ראינו בהרצאות מבני נתונים נוספים עצים בינאריים עצי חיפוש בינאריים תור מחסנית
נראה בתרגול מבני נתונים חדשים תור ממשק + מימוש + שאלה עץ חיפוש בינארי תזכורת + 3 שאלות
תרגולים קודמים ממשקים: Iterable Iterator Comparable Comparator מחלקות המחלקה Object הורשה Generics עצים בינאריים BinaryNode BinaryTree סריקות
תור - Queue )FIFO( מבנה נתונים המשמר First In First Out מערכת הזמנות ניהול משימות במערכת הפעלה המתנה לשירות לקוחות טלפוני
public interface Queue<T> extends Iterable<T>{ /** * Checks if the queue is empty or not. * @return true if the queue is empty */ public boolean isempty(); /** * Removes an element from the head of the queue. * (FIFO order) * @return the next element in the queue. */ public T dequeue(); /** * Inserts an element into the queue. * @param elemment the element to be enqueued. */ public void enqueue(t element); /** * Returns the top element without removing it. * @return the next element in the queue. */ public T peek(); ממשק תור
ממשק רשימה )חלקי( public interface List<T> extends Iterable<T> { //Appends the specified element to the end of this list public boolean add(t element); //Inserts the specified element at the specified position in this list public void add(int index, T element); //Returns the element at the specified position in this list. public T get(int index); //Removes the first occurrence of the specified element from this list, if it is present public boolean remove(t element); //Removes the element at position i and returns it. public T remove(int index); //Returns true if this list contains no elements. public boolean isempty();
מימוש ע י רשימה מקושרת public class QueueAsLinkedList<T> implements Queue<T> { private List<T> list; public QueueAsLinkedList() { this.list {? = new LinkedList<>(); public boolean isempty() {{? return list.isempty(); public void enqueue(t element) {{? list.add(element); public T dequeue() {?{ if (isempty()) {throw new NoSuchElementException(); T element = list.get(0); list.remove(element); return element; // return list.remove(0); public T peek() {? { if (isempty()) {throw new NoSuchElementException(); return list.get(0); public Iterator<T> iterator() { {? return list.iterator();
טורניר סימולציה של טורניר
טורניר בהנתן המחלקה Player המדמה שחקן ופונקציה סטאטית p2) Player getwinner(player p1, Player המסמלצת משחק בין שני שחקנים ומחזירה את המנצח )אין אפשרות ל"תיקו" או להחזרת.)NULL יש לממש את הפונקציה הבאה: public static Player simulatetournament(list<player> playerslist) אשר מקבלת רשימה של שחקנים)לא )NULL טורניר טניס: בשלב הראשון השחקנים מתחלקים לזוגות מכל זוג עולה המנצח לשלב הבא השחקנים המנצחים מתחלקים לזוגות ומתחרים מסיימים כשנותר מנצח בודד ומבצעת סימולציה של
דוגמה של תור - טורניר 4 שחקן 2 שחקן 3 שחקן 4 שלב 1: שחקן 1 שחקן 4 שחקן 3 שחקן 2 שחקן 1
דוגמה של תור - טורניר שחקן 2 שלב 2: 4 שחקן 2 שחקן 3 שחקן 4 שלב 1: שחקן 1 שחקן 4 שחקן 3 שחקן 2
דוגמה של תור - טורניר שחקן 4 שחקן 2 שלב 2: 4 שחקן 2 שחקן 3 שחקן 4 שלב 1: שחקן 1 שחקן 4 שחקן 2
דוגמה של תור - טורניר שחקן 2 שלב 3 )המנצח(: שחקן 4 שחקן 2 שלב 2: 4 שחקן 2 שחקן 3 שחקן 4 שלב 1: שחקן 1 שחקן 2
דוגמה של תור - טורניר public static Player simulatetournament(list<player> playerslist) { // Add all players to a queue Queue<Player> q = new QueueAsLinkedList<>(); Iterator<Player> it = playerslist.iterator(); Player winner = null; while (it.hasnext()) { q.enqueue(it.next()); // Start the tournament! while (!q.isempty()) { Player first = q.dequeue(); if (q.isempty()) { winner = first; // Last player wins else { Player second = q.dequeue(); Player matchwinner = getwinner(first, second); // compete q.enqueue(matchwinner); // add winner to queue return winner;
עץ חיפוש בינארי 5 עץ בינארי 2 8 )next לכל קודקוד יש לכל היותר שני בנים )"רשימה" עם שני מבנה רקורסיבי 1 7 9 עץ חיפוש בינארי עץ בינארי כל קודקוד גדול מכל קודקודי תת העץ השמאלי וקטן מכל קודקודי תת העץ הימני
עץ בינארי תזכורת
עץ חיפוש בינארי מציאת איבר מינימלי איך נמצא איבר מינימלי בעץ בינארי )לא חיפוש(? נעבור על כל העץ 5 איך נמצא איבר מינימלי בעץ חיפוש בינארי? נתקדם תמיד לבן השמאלי 2 8 1 7 9
עץ חיפוש בינארי מציאת איבר מינימלי public class BinarySearchTree<T> extends BinaryTree<T> { private Comparator<T> treecomparator;... public BinarySearchTree(Comparator<T> mycomparator) { super(); this.treecomparator = mycomparator; public T findmin() { if (isempty()) return null; else return root.findmin();...
עץ חיפוש בינארי מציאת איבר מינימלי public class BinarySearchNode<T> extends BinaryNode<T> { private Comparator<T> treecomparator;... public BinarySearchNode(T data, Comparator<T> mycomparator) { super(data); this.treecomparator = mycomparator; public T findmin() { BinaryNode<T> currnode = this; while (currnode.left!= null) { currnode = currnode.left; return currnode.data;...
איטרטור עם זיכרון קבוע נתון עץ חיפוש בינארי בו כל קודקוד מכיל הפנייה לקודקוד האב שלו public class BinaryWithParentNode<T> { protected T data; protected BinaryNode<T> left; protected BinaryNode<T> right; protected BinaryNode<T> parent;... כתבו איטרטור in-order עבור העץ המשתמש בזכרון שאינו תלוי בעץ. הדרכה עבור כל תת עץ, מי הקודקוד הראשון לפי סדר הסריקה? מציאת "מינימום" בן שמאלי ביותר אם לקודקוד הנוכחי יש בן ימני, מי הקודקוד הבא בסריקה? המינימום בתת העץ הימני אם לקודקוד הנוכחי אין בן ימני, מי הקודקוד הבא בסריקה? הקודקוד הראשון במסלול מהקודקוד הנוכחי לשורש עבורו הקודקוד הנוכחי נמצא בתת העץ השמאלי שלו
איטרטור עם זיכרון קבוע public T findleftmost() { BinaryWithParentNode<T> currnode = this; while (currnode.left!= null) { currnode = currnode.left; return currnode.data; מציאת "מינימום"
איטרטור עם זיכרון קבוע! מציאת אב קדמון השמאלי )הקרוב ביותר( "אני" עבורו נמצא בתת העץ המושרש בבנו public BinaryWithParentNode<T> ancestor() { BinaryWithParentNode<T> ans = this; if (parent == null parent.left == this) ans = parent; else ans = parent.ancestor(); return ans;
מימוש איטרטור עם זיכרון קבוע! public class InOrderIterator<T> implement Iterator<T>{ private BinaryWithParentNode<T> next; public InOrderIterator<T>(BinaryWithParentNode<T> root){ if(root!= null) {next = root.findleftmost(); else {next = null; public boolean hasnext(){ return next!= null; public T next(){ if (!hasnext()) { throw new NoSuchElementException(); T ans = next.getdata(); if (next.right!= null) next = next.right.findleftmost(); else next = next.ancestor(); return ans;
post-order iterator עץ בינארי post-order יש לממש iterator למעבר על עץ בינארי )לאו דווקא חיפוש( פתרון אפשרי ניצור עץ איטרטורים - איטרטור אחד עבור כל צומת בעץ המקורי. כל איטרטור יחזיק את הבנים שלו, את הערך בקודקוד המתאים מהעץ והאם יש עוד ערך להחזיר. 5 5,T 2 8 2,F 8,T 1 7 9 1,F 7,F 9,T
post-order iterator עץ בינארי public class TreePostOrderIterator>T< implements Iterator>T<{ private boolean hasnext; private T rootdata; private Iterator>T< leftchilditerator, rightchilditerator; public TreePostOrderIterator(BinaryNode>T< root){ if (root== null){ hasnext = false; else{ hasnext = true; rootdata = root.getdata(); leftchilditerator = new TreePostOrderIterator>T<(root.getLeft()); rightchilditerator = new TreePostOrderIterator>T<(root.getRight());
post-order iterator עץ בינארי public boolean hasnext(){ return hasnext; public T next() { if (!hasnext()) { throw new NoSuchElementException(); if (leftchilditerator.hasnext()) return leftchilditerator.next(); else if (rightchilditerator.hasnext()) return rightchilditerator.next(); else{ hasnext = false; return rootdata; // Will never reach this part, but needed for compilation return null;
סיכום ומשימות בינארים תרגלנו: תור עצי חיפוש משימות: מטלת בית 5 קוויז